#include <iostream>

using namespace std;

class Base {
    public:
        virtual int fcn() { cout << "Base::fcn()" << endl; return 0; }
};

class D1 : public Base {
    public:
        // 隐藏基类的 fcn，这个 fcn 不是虚函数
        // D1 继承了 Base::fcn() 的定义
        int fcn(int i)                  // 形参列表与 Base 中的 fcn 不一致
            { cout << "D1::fcn(" << i << ")" << endl; return i; }
        virtual void f2()               // 是一个新的函数，在 Base 中不存在
            { cout << "D1::f2()" << endl; }            
};

class D2 : public D1 {
    public:
        int fcn(int i)                  // 是一个非虚函数，隐藏了 D1::fcn(int)
            { cout << "D2::fcn(" << i << ")" << endl; return i; }
        int fcn()                       // 覆盖了 Base 的虚函数 fcn
            { cout << "D2::fcn()" << endl; return 0; }
        void f2()                       // 覆盖了 D1 的虚函数 f2
            { cout << "D2::f2()" << endl; }
};

int main()
{
    Base bobj; D1 d1obj; D2 d2obj;

    Base *bp1 = &bobj, *bp2 = &d1obj, *bp3 = &d2obj;
    bp1->fcn();                 // 虚调用，将在运行时调用 Base::fcn
    bp2->fcn();                 // 虚调用，将在运行时调用 Base::fcn
    bp3->fcn();                 // 虚调用，将在运行时调用 D2::fcn

    D1 *d1p = &d1obj; D2 *d2p = &d2obj;
    // bp2->f2();               // 错误：Base 没有名为 f2 的成员
    d1p->f2();                  // 虚调用，将在运行时调用 D1::f2()
    d2p->f2();                  // 虚调用，将在运行时调用 D2::f2()

    Base *p1 = &d2obj; D1 *p2 = &d2obj; D2 *p3 = &d2obj;
    // p1->fcn(42);             // 错误：Base 中没有接受一个 int 的 fcn
    p2->fcn(42);                // 静态绑定，调用 D1::fcn(int)
    p3->fcn(42);                // 静态绑定，调用 D2::fcn(int)
}